import { Component, OnInit } from '@angular/core';
import { Observable, Subject, asapScheduler, pipe, of, from, interval, merge, fromEvent, timer, observable } from 'rxjs';
import { map, filter, scan, take, concatAll, concatMap, takeUntil, retry, retryWhen } from 'rxjs/operators';
import { webSocket } from 'rxjs/webSocket';
import { ajax } from 'rxjs/ajax';
import { TestScheduler } from 'rxjs/testing';

@Component({
    selector: 'app-drag-drop',
    template: `<div id="box" style="width:100px;height:100px;background:#000;position:absolute;">`,
    // styleUrls: ['./name.component.scss']
})
export class DragDropComponent implements OnInit {
    constructor() { }

    ngOnInit(): void {
        const box = document.querySelector('#box');
        const mouseDown$ = fromEvent(box, 'mousedown');
        const mouseUp$ = fromEvent(box, 'mouseup');
        const mouseOut$ = fromEvent(box, 'mouseout');
        const mouseMove$ = fromEvent(box, 'mousemove');

        const drag$ = mouseDown$.pipe(
            concatMap(start => {
                const initialLeft = (<any>box).offsetLeft;
                const initialTop = (<any>box).offsetTop;
                const stop$ = merge(mouseUp$, mouseOut$);
                return mouseMove$.pipe(
                    takeUntil(mouseUp$),
                    map(move => {
                        return {
                            x: (<any>move).x - (<any>start).x + initialLeft,
                            y: (<any>move).y - (<any>start).y + initialTop
                        };
                    })
                );
            })
        );

        drag$.subscribe(event => {
            (<any>box).style.left = event.x + 'px';
            (<any>box).style.top = event.y + 'px';
        });


        const source$ = interval(1000);
        const error$ = source$.pipe(map(x => {
            if (x === 4) {
                throw new Error('unlucky number');
            }
            return x;
        }));
        const final$ = error$.pipe(
            retryWhen((err$ => {
                return err$;
                // return of('x');
            })
        ));
        final$.subscribe(x => { console.log(x); });
    }
}
